package com.zm.demo.core.lambda;

import javafx.collections.transformation.SortedList;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.stream.Collectors;

import static java.lang.System.out;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.maxBy;
import static java.util.stream.Collectors.minBy;
import static java.util.stream.Collectors.summingDouble;
import static java.util.stream.Collectors.summingInt;
import static java.util.stream.Collectors.summingLong;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

/**
 * @author zoum
 * @create 2019/7/2 16:16
 */
public class CollectorsTest {

    @Test
    public void toCollectionTest(){
        List<Integer>list1 = Arrays.asList(1,3,5,7,2,4,6,8,9,1);
        out.println(list1.stream().collect(toCollection(() -> new TreeSet<>())).toString());
        out.println(list1.stream().collect(toCollection(() -> new LinkedList<>())).toString());
    }

    @Test
    public void toListTest(){
        HashSet<Integer> set = new HashSet<>();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);
        out.println(set.stream().collect(toList()).toString());

        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        linkedList.add(4);
        out.println(linkedList.stream().collect(toList()).toString());
    }

    @Test
    public void toSetTest(){
        BlockingDeque<Integer> deque = new LinkedBlockingDeque<>();
        deque.add(1);
        deque.add(2);
        deque.add(3);
        deque.add(4);
        out.println(deque.stream().collect(toSet()).toString());

        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        linkedList.add(4);
        out.println(linkedList.stream().collect(toSet()).toString());
    }

    @Test
    public void joiningTest(){
        BlockingDeque<String> deque = new LinkedBlockingDeque<>();
        deque.add("1");
        deque.add("2");
        deque.add("3");
        deque.add("5");
        out.println(deque.stream().collect(joining()).toString());

        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("3");
        linkedList.add("8");
        linkedList.add("3");
        linkedList.add("5");
        out.println(linkedList.stream().collect(joining("-")).toString());
        out.println(linkedList.stream().collect(joining("-","(", ")")).toString());
    }

    @Test
    public void mappingTest(){
        class Person{
            String name;
            String city;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getCity() {
                return city;
            }

            public void setCity(String city) {
                this.city = city;
            }
        }
        Person person = new Person();
        person.setName("1");
        person.setCity("上海");
        Person person2 = new Person();
        person2.setName("2");
        person2.setCity("上海");
        Person person3 = new Person();
        person3.setName("3");
        person3.setCity("北京");

        Person person4 = new Person();
        person4.setName("5");
        person4.setCity("北京");

        List<Person> list = new ArrayList<>();
        list.add(person);
        list.add(person2);
        list.add(person3);
        list.add(person4);
        out.println(list.stream().collect(groupingBy(Person::getCity, mapping(p -> p.getName(), toList()))).toString());

    }

    @Test
    public void collectingAndThenTest(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        List<Integer> list1 = list.stream().collect(collectingAndThen(toList(), s -> new CopyOnWriteArrayList<>(s)));
        out.println(list1);

    }

    @Test
    public void countingTest(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        Long count = list.stream().collect(counting());
        out.println(count);

    }

    @Test
    public void minByTest() throws Exception{
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        Integer i = list.stream().collect(minBy(Comparator.comparing(Integer::intValue))).orElseThrow(() -> new Exception());
        out.println(i);

    }

    @Test
    public void maxByTest() throws Exception{
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        Integer i = list.stream().collect(maxBy(Comparator.comparing(Integer::intValue))).orElseThrow(() -> new Exception());
        out.println(i);
    }

    @Test
    public void summingIntTest() throws Exception{
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        Integer i = list.stream().collect(summingInt(Integer::new));
        out.println(i);
    }

    @Test
    public void summingLongTest() throws Exception{
        List<Long> list = Arrays.asList(1L,2L,3L,4L,5L,6L,7L);
        long i = list.stream().collect(summingLong(j -> j));
        out.println(i);
    }

    @Test
    public void summingDoubleTest() throws Exception{
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
        double dd = list.stream().mapToDouble(j -> j.doubleValue()).boxed().collect(summingDouble(Double::new));
        out.println(dd);
    }

    @Test
    public void summingDouble1Test() throws Exception{
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
        double dd = list.stream().mapToDouble(j -> j.doubleValue()).boxed().collect(summingDouble(Double::new));
        out.println(dd);
    }

}
